package com.xiaohua.api.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.xiaohua.common.service.ITokenService;

/**
 * Token服务实现类
 * 
 * @author 小花
 */
@Service
@Primary
public class XhApiTokenServiceImpl implements ITokenService {

    private static final Logger log = LoggerFactory.getLogger(XhApiTokenServiceImpl.class);
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    /**
     * 检查用户tokens是否足够
     * 
     * @param userId 用户ID
     * @return 如果用户tokens足够返回true，否则返回false
     */
    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public boolean checkUserTokens(Long userId) {
        if (userId == null || userId <= 0) {
            log.error("非法用户ID：{}", userId);
            return false;
        }
        
        try {
            // 直接查询用户表，获取tokens数量
            String sql = "SELECT tokens FROM xh_users WHERE user_id = ?";
            Long tokens = jdbcTemplate.queryForObject(sql, Long.class, userId);
            
            boolean hasTokens = tokens != null && tokens > 0;
            log.info("用户[{}]token检查: 当前tokens={}, 是否足够={}", userId, tokens, hasTokens);
            
            return hasTokens;
        } catch (EmptyResultDataAccessException e) {
            log.error("用户[{}]不存在", userId);
            return false;
        } catch (DataAccessException e) {
            log.error("数据库访问错误，用户ID={}, 错误={}", userId, e.getMessage(), e);
            return false;
        } catch (Exception e) {
            log.error("检查用户tokens时发生未知错误，用户ID={}, 错误={}", userId, e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 扣减用户tokens
     * 
     * @param userId 用户ID
     * @param amount 扣减的tokens数量
     * @return 扣减成功返回true，否则返回false
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean deductUserTokens(Long userId, int amount) {
        if (userId == null || userId <= 0) {
            log.error("非法用户ID：{}", userId);
            return false;
        }
        
        if (amount <= 0) {
            log.error("无效的扣减数量: {}, 用户ID={}", amount, userId);
            return false;
        }
        
        try {
            // 使用乐观锁确保并发时数据一致性
            String selectSql = "SELECT tokens FROM xh_users WHERE user_id = ? FOR UPDATE";
            Long tokens = jdbcTemplate.queryForObject(selectSql, Long.class, userId);
            
            if (tokens == null) {
                log.error("用户[{}]不存在", userId);
                return false;
            }
            
            if (tokens < amount) {
                log.warn("用户[{}]tokens不足: 当前={}, 需要={}", userId, tokens, amount);
                return false;
            }
            
            // 执行扣减 - 使用参数化SQL防止SQL注入
            String updateSql = "UPDATE xh_users SET tokens = tokens - ? WHERE user_id = ? AND tokens >= ?";
            int rows = jdbcTemplate.update(updateSql, amount, userId, amount);
            
            if (rows > 0) {
                log.info("用户[{}]tokens扣减成功: 扣减前={}, 扣减数量={}, 剩余={}", 
                        userId, tokens, amount, (tokens - amount));
                return true;
            } else {
                log.error("用户[{}]tokens扣减失败: 当前tokens={}, 可能并发导致数据不一致", userId, tokens);
                return false;
            }
        } catch (EmptyResultDataAccessException e) {
            log.error("用户[{}]不存在", userId);
            return false;
        } catch (DataAccessException e) {
            log.error("数据库错误，无法扣减用户tokens，用户ID={}, 错误={}", userId, e.getMessage(), e);
            throw e; // 抛出异常以触发事务回滚
        } catch (Exception e) {
            log.error("扣减用户tokens时发生未知错误，用户ID={}, 错误={}", userId, e.getMessage(), e);
            throw e; // 抛出异常以触发事务回滚
        }
    }
    
    /**
     * 扣减用户tokens，默认扣减1个token
     * 
     * @param userId 用户ID
     * @return 扣减成功返回true，否则返回false
     */
    @Override
    public boolean deductUserTokens(Long userId) {
        return deductUserTokens(userId, 1);
    }
} 